#include "server.h"

struct cnfg_info cnfg_info;
struct stat_info stat_info;

extern int worker_start();

static int _cnfg(char *argv0)
{/*{{{*/
    char dirname[LONG_FILE_NM_SIZE+1];
    char buf[LONG_FILE_NM_SIZE+1];
    int res;
    CNFG cnfg;
    struct cnfg_property property;

    extract_dirname(argv0, dirname);

    /*----- cnfg -----*/
    sprintf(buf, "%s/server.cnfg", dirname);
    res=cnfg_load(buf, &cnfg);
    if(res)
    {
        if(res > 0)
            fprintf(stderr, "%s: line %d error\n", __func__, res);
        else
            fprintf(stderr, "%s: load server.cnfg fail, res:%d\n",
                    __func__, res);
        return(-1);
    }

    /*--- ERRLOG ---*/
#ifdef _MY_DEBUG
    CLR_BUF(cnfg_info._errlog_.location);
#else
    strcpy(cnfg_info._errlog_.location, "./_log");
    res=cnfg_get_property(cnfg, "ERRLOG", "LOCATION", 0, &property);
    if(res)
    {
        if(res != RET_ERR_CNFG_PROPERTY_NOT_FOUND)
        {
            fprintf(stderr, "%s: get ERRLOG.LOCATION fail, res:%d\n",
                    __func__, res);
            return(-1);
        }
    }
    else
    {
        if(!BUF_IS_CLR(property.value))
            strcpy(cnfg_info._errlog_.location, property.value);
    }
#endif
    res=cnfg_get_property(cnfg, "ERRLOG", "TRACKING", 0, &property);
    if(res)
    {
        if(res != RET_ERR_CNFG_PROPERTY_NOT_FOUND)
        {
            fprintf(stderr, "%s: get ERRLOG.TRACKING fail, res:%d\n",
                    __func__, res);
            return(-1);
        }
        cnfg_info._errlog_.tracking=IS_FALSE;
    }
    else
        cnfg_info._errlog_.tracking=IS_TRUE;

    // USER
    CLR_BUF(cnfg_info.user);
    res=cnfg_get_property(cnfg, NULL, "USER", 0, &property);
    if(res)
    {
        if(res != RET_ERR_CNFG_PROPERTY_NOT_FOUND)
        {
            fprintf(stderr, "%s: get USER fail, res:%d\n",
                    __func__, res);
            return(-1);
        }
    }
    else
    {
        if(!BUF_IS_CLR(property.value))
        {
            if(strlen(property.value) > NAME_SIZE)
            {
                fprintf(stderr, "%s: USER invalid\n", __func__);
                return(-1);
            }
            strcpy(cnfg_info.user, property.value);
        }
    }

    /*--- ACCESS ---*/
    // SERVER_PORT
    res=cnfg_get_property(cnfg, "ACCESS", "SERVER_PORT", 0, &property);
    if(res)
    {
        fprintf(stderr, "%s: get ACCESS.SERVER_PORT fail, errcode:%d\n",
                __func__, res);
        return(-1);
    }
    if(BUF_IS_CLR(property.value) || (res=atoi(property.value)) < 1024)
    {
        fprintf(stderr, "%s: ACCESS.SERVER_PORT invalid\n", __func__);
        return(-1);
    }
    cnfg_info._access_.server_port=res;

    // MONITOR_PORT
    res=cnfg_get_property(cnfg, "ACCESS", "MONITOR_PORT", 0, &property);
    if(res)
    {
        fprintf(stderr, "%s: get ACCESS.MONITOR_PORT fail, errcode:%d\n",
                __func__, res);
        return(-1);
    }
    if(BUF_IS_CLR(property.value) || (res=atoi(property.value)) < 1024)
    {
        fprintf(stderr, "%s: ACCESS.MONITOR_PORT invalid\n", __func__);
        return -1;
    }
    cnfg_info._access_.monitor_port=res;

    /*--- DB ---*/
    res=cnfg_get_property(cnfg, "DB", "USER", 0, &property);
    if(res || BUF_IS_CLR(property.value)
            || strlen(property.value) > NAME_SIZE)
    {
        fprintf(stderr, "%s: DB.USER invalid\n", __func__);
        return(-1);
    }
    strcpy(cnfg_info._db_.user, property.value);

    res=cnfg_get_property(cnfg, "DB", "PASSWD", 0, &property);
    if(res || BUF_IS_CLR(property.value)
            || strlen(property.value) > PASSWD_ENC_SIZE)
    {
        fprintf(stderr, "%s: DB.PASSWD invalid\n", __func__);
        return(-1);
    }
    strcpy(cnfg_info._db_.passwd, property.value);

    res=cnfg_get_property(cnfg, "DB", "DATABASE", 0, &property);
    if(res || BUF_IS_CLR(property.value)
            || strlen(property.value) > NAME_SIZE)
    {
        fprintf(stderr, "%s: DB.DATABASE invalid\n", __func__);
        return(-1);
    }
    strcpy(cnfg_info._db_.database, property.value);

    CLR_BUF(cnfg_info._db_.host);
    res=cnfg_get_property(cnfg, "DB", "HOST", 0, &property);
    if(res)
    {
        if(res != RET_ERR_CNFG_PROPERTY_NOT_FOUND)
        {
            fprintf(stderr, "%s: get DB.HOST fail, res:%d\n",
                    __func__, res);
            return(-1);
        }
    }
    else
    {
        if(!BUF_IS_CLR(property.value))
        {
            if(strlen(property.value) > NAME_SIZE)
            {
                fprintf(stderr, "%s: DB.HOST invalid\n", __func__);
                return(-1);
            }
            strcpy(cnfg_info._db_.host, property.value);
        }
    }

    /*--- DB_LOCAL ---*/
    // LOCATION
    CLR_BUF(cnfg_info._db_local_.location);
    res=cnfg_get_property(cnfg, "DB_LOCAL", "LOCATION", 0, &property);
    if(res)
    {
        if(res != RET_ERR_CNFG_PROPERTY_NOT_FOUND)
        {
            fprintf(stderr, "%s: get DB_LOCAL.LOCALTION fail, res:%d\n",
                    __func__, res);
            return(-1);
        }
    }
    else
    {
        if(!BUF_IS_CLR(property.value))
            strcpy(cnfg_info._db_local_.location, property.value);
    }

    cnfg_free(cnfg);

    return(0);
}/*}}}*/

static int _start(char *argv0)
{/*{{{*/
    int res;

    sig_ignore(SIGPIPE);
    ep_init();
    //    mysqlc_init();
    //    oraproc_init();

#ifdef _MY_DEBUG
    init_errlog(argv0, NULL);
#else
    res=init_errlog(argv0, cnfg_info._errlog_.location);
    if(res)
    {
        fprintf(stderr, "%s: init_errlog fail, res:%d\n",
                __func__, res);
        return(-1);
    }
#endif

    if(getuid() == 0)
    {
        struct passwd *user=getpwnam(cnfg_info.user);
        if(user)
        {
            if(setuid(user->pw_uid) == -1)
            {
                fprintf(stderr, "Change to user %s fail\n",
                        cnfg_info.user);
                return(-1);
            }
            fprintf(stderr, "Change to user %s\n", cnfg_info.user);
        }
        else
        {
            fprintf(stderr, "User %s not found, keep root\n",
                    cnfg_info.user);
        }
    }

    //    res=mysqlc_connect_ex(cnfg_info._db_.user,
    //                    cnfg_info._db_.passwd,
    //                    cnfg_info._db_.database,
    //                    cnfg_info._db_.host,
    //                    &cnfg_info._db_.db);
    //    if(res != MY_OK)
    //    {
    //        fprintf(stderr, "%s: connect to db fail, res:%d\n",
    //                __func__, res);
    //        return(-1);
    //    }
    //
    //    res=oraproc_connect_ex(cnfg_info._db_.user,
    //                    cnfg_info._db_.passwd,
    //                    cnfg_info._db_.host,
    //                    &cnfg_info._db_.db);
    //    if(res != ORA_OK)
    //    {
    //        fprintf(stderr, "%s: connect to db fail, res:%d\n",
    //                __func__, res);
    //        return(-1);
    //    }
    //
    //    sprintf(buf, "%s/test.dbf", cnfg_info._db_local_.location); 
    //    res=sqlic_connect(buf, &cnfg_info._db_local_.db);
    //    if(res != SQLI_OK)
    //    {
    //        fprintf(stderr, "%s: connect to %s fail, res:%d\n",
    //                __func__, buf, res);
    //        return(-1);
    //    }

    return(worker_start());
}/*}}}*/

int main(int argc, char *argv[])
{
#ifndef _MY_DEBUG
    daemon(1, 1);
#endif
    if(_cnfg(argv[0]))
        return(-1);
    return(_start(argv[0]));
}
